<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>

/*
    * 创建对象的方式：字面量、new、Object.create()
    * 使用Object.create()第一个参数为原型对象，第二个参数为一个参数的描述
*/
    var o = Object.create({x:1,y:2}); //o->prototype->{x:1,y:2}
    var o1 = Object.create(null); //将不继承任何属性和方法
    var o3 = Object.create(Object.prototype); //为一个普通对象

    /*constructor的作用*/
    // var v1 = function(){};
    function Fun(age, weight, type) {
        this.age = age;
        this.weight = weight;
        this.type = type;
    }
    var v2 = Fun.prototype;
    var v3 = v2.constructor;
    // console.log('test=>', v3 === Fun);  //true


/*所谓的面向对象，就是找到对象，然后使用对象的方法和属性;
    * 面向过程 vs 面向对象
    * 使用构造函数创建对象  Animal、Fridge
    * 创建把大象装容器的方法
    * 封装：把每个分类使用构造函数表示（解决重复创建对象的问题）
*/
    function Animal(age,weight,type){
        this.age=age;
        this.weight=weight;
        this.type=type;
        /*初级写法：把方法写入构造函数*/
        this.enterContainer=function(){console.log('进入了容器！')}
    }
    // // var elephant = new Animal(11,200,'非洲象');
    // // var lion = new Animal(11,100,'狮子');
    // //
    // // /**容器*/
    function Fridge(width,height){
        this.width=width;
        this.height=height;
        this.openDoor=function(){};
        this.closeDoor=function(){};
    }
    // // var container = new Fridge('4m','4m');
    // // container.openDoor(); /*打开冰箱指令*/
    // // elephant.enterContainer(); /*大象进入容器指令*/
    // // lion.enterContainer(); /*狮子进入容器指令*/
    // // container.closeDoor();/*关闭冰箱指令*/
    //
    // /*解决猴子要爬树的问题
    // * 缺点：除climbingTree这个方法外，其他属性方法都一样这时出现了很多重复代码
    // * 解决：使用原型来实现继承（每个构造函数都有一个prototype属性，也是一个对象，prototype中的方法可以被实例对象共享）
    // * Monkey实例共享enterContainer方法
    // * */
    function Monkey(age,weight,type){
        this.age=age;
        this.weight=weight;
        this.type=type;
        this.climbingTree=function(){};
    }
    Monkey.prototype = new Animal();
    // var M1 = new Monkey(10,50,'长臂猿');
    // var M2 = new Monkey(10,50,'金丝猴');
    // console.log(M1,M2);
    //
    // /*缺点：climbingTree方法写在构造函数内，每次new实例内存中都会声明这个函数，而函数的代码都是一样的，浪费内存
    // * 解决：把方法写在原型上
    // * */
    function Animal(age, weight, type) {
        this.age = age;
        this.weight = weight;
        this.type = type;
    }
    Animal.prototype.enterContainer = function () {
        console.log('进入了容器');
    }

    function Monkey(age,weight,type){
        this.age = age;
        this.weight = weight;
        this.type = type;
    }
    Monkey.prototype = new Animal();
    Monkey.prototype.climbingTree = function(){
        console.log('小猴子正在爬树');
    }
    var m1 = new Monkey(10,50,'长臂猿');
    var m2 = new Monkey(10,50,'金丝猴');
    // console.log(m1,m2);
    // m1.climbingTree();
    // m2.climbingTree();

/*解决代码重用问题(对象属性)
    * 使用.call()方法继承父类的属性
    * 以下两种继承方式称：组合继承
*/
    function Animal(age, weight, type) {
        this.age = age;
        this.weight = weight;
        this.type = type;
    }
    Animal.prototype.enterContainer = function () {
        console.log('进入了容器');
    }

    function Monkey(age,weight,type){
        Animal.call(this,age,weight,type) /*继承父类的属性减少代码量*/
    }
    /*1.子类继承父类的方法：父类方法直接赋值给子类*/
    // Monkey.prototype.enterContainer = Animal.prototype.enterContainer;
    /*2.子类的原型继承父类的原型*/
    Monkey.prototype=Object.create(Animal.prototype);
    Monkey.prototype.constructor=Monkey;
    Monkey.prototype.climbingTree = function(){
        console.log('小猴子正在爬树');
    }
    // var m1 = new Monkey(11,'15kg','长臂猴');
    // var m2 = new Monkey(12,'25kg','大马猴');
    // console.log(m1);
    // m1.enterContainer();
    // m1.climbingTree();

/*面向对象ES6: Class关键字
* 类的方法都是定义在prototype对象上面
* constructor是类的默认方法使用new生成对象实例时调用
* this指向实例对象
* 使用 子extends父 super(调用父类的constructor) 实现继承
* */
    class Animals{
    constructor(age,weight,type){
        this.age = age;
        this.weight = weight;
        this.type = type;
    }
    enterContainer(){console.log('进入容器')}
}
// var a1=new Animals(11,'500', '大象');
// console.log(a1.constructor === Animals.prototype.constructor); //true
// a1.enterContainer();

class Monkeys extends Animals{
    constructor(age,weight,type){
        super(age,weight,type);
    }
    climbingTree(){
        console.log('小猴子正在爬树');
    }
}
// let monkeys = new Monkeys('12','45', '金丝猴');
// monkeys.climbingTree();
// monkeys.enterContainer();
// console.log(monkeys);



</script>
</body>
</html>